package com.quincysx.customaidl.demo1;

import android.os.Binder;
import android.os.IBinder;
import android.os.IInterface;
import android.os.Parcel;
import android.os.RemoteException;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.quincysx.customaidl.bean.Book;

import java.util.List;

/**
 * @author QuincySx
 * @date 2018/5/4 上午11:54
 */
public interface IBookManager extends IInterface {
    void addBook(Book book) throws RemoteException;

    List<Book> getBookList() throws RemoteException;

    public abstract static class Stub extends Binder implements IBookManager {
        private static final String DESCRIPTOR = "com.quincysx.customaidl.demo1.IBookManager";
        private static final int TRANSACTION_addBook = 1;
        private static final int TRANSACTION_getBookList = 2;

        public Stub() {
            this.attachInterface(this, DESCRIPTOR);
        }

        public final static IBookManager asInterface(IBinder binder) {
            if (binder == null) {
                return null;
            }
            IInterface iin = binder.queryLocalInterface(DESCRIPTOR);
            if (iin != null && iin instanceof IBookManager) {
                return (IBookManager) iin;
            }
            return new Proxy(binder);
        }

        @Override
        public IBinder asBinder() {
            return this;
        }

        @Override
        protected boolean onTransact(int code, @NonNull Parcel data, @Nullable Parcel reply, int
                flags) throws RemoteException {
            switch (code) {
                case INTERFACE_TRANSACTION:
                    reply.writeString(DESCRIPTOR);
                    return true;
                case TRANSACTION_addBook:
                    data.enforceInterface(DESCRIPTOR);
                    Book book;
                    if (data.readInt() == 0) {
                        book = null;
                    } else {
                        book = Book.CREATOR.createFromParcel(data);
                    }
                    addBook(book);
                    reply.writeNoException();
                    return true;
                case TRANSACTION_getBookList:
                    data.enforceInterface(DESCRIPTOR);
                    List<Book> books = getBookList();
                    reply.writeNoException();
                    reply.writeTypedList(books);
                    return true;
            }
            return super.onTransact(code, data, reply, flags);
        }

        public static class Proxy implements IBookManager {
            private IBinder mRemote;

            public Proxy(IBinder remote) {
                mRemote = remote;
            }

            @Override
            public void addBook(Book book) throws RemoteException {
                Parcel data = Parcel.obtain();
                Parcel reply = Parcel.obtain();
                try {
                    data.writeInterfaceToken(DESCRIPTOR);
                    if (book == null) {
                        data.writeInt(0);
                    } else {
                        data.writeInt(1);
                        book.writeToParcel(data, 0);
                    }
                    mRemote.transact(TRANSACTION_addBook, data, reply, 0);
                    reply.readException();
                } finally {
                    data.recycle();
                    reply.recycle();
                }
            }

            @Override
            public List<Book> getBookList() throws RemoteException {
                Parcel data = Parcel.obtain();
                Parcel reply = Parcel.obtain();
                List<Book> books;
                try {
                    data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact(TRANSACTION_getBookList, data, reply, 0);
                    reply.readException();
                    books = reply.createTypedArrayList(Book.CREATOR);
                } finally {
                    data.recycle();
                    reply.recycle();
                }
                return books;
            }

            @Override
            public IBinder asBinder() {
                return mRemote;
            }
        }
    }
}
